﻿/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/


#include "MkBuffer.h"

CMkBuffer::CMkBuffer(const CMkBuffer& Other)
    : m_nLen(Other.GetLength())
    , m_pBuf(Other.GetBuffer())
{
}

CMkBuffer::CMkBuffer(const void* pBuf, Uint32 nLen)
    : m_nLen(nLen)
    , m_pBuf(pBuf)
{
}

CMkBufferList::CMkBufferList()
    : m_TotalLen(0)
{

}

CMkStorageBuffer::CMkStorageBuffer(const CMkBuffer& MkBuffer)
    : m_nLen(MkBuffer.GetLength())
    , m_BuildTime(NowMkTime)
{
    m_pBuf = malloc(m_nLen);
    memcpy(m_pBuf, MkBuffer.GetBuffer(), m_nLen);
}

CMkStorageBuffer::CMkStorageBuffer(const void* pBuf, Uint32 nLen)
    : m_nLen(nLen)
    , m_BuildTime(NowMkTime)
{
    m_pBuf = malloc(m_nLen);
    memcpy(m_pBuf, pBuf, m_nLen);
}

//CMkStorageBuffer::CMkStorageBuffer(const CMkStorageBuffer& StorageBuffer)
//{
//
//}

Uint32 CMkBufferList::InsertHead(const CMkBufferList& BufList)
{
    MkListBuffer::const_reverse_iterator it = BufList.GetBufferList().rbegin();
    for (; it != BufList.GetBufferList().rend(); it++) {
        InsertHead(*it);
    }
    return NoneError;
}

Uint32 CMkBufferList::InsertHead(const CMkBuffer& Buffer)
{
    m_ListBuffer.push_front(Buffer);
    m_TotalLen += Buffer.GetLength();
    return NoneError;
}

Uint32 CMkBufferList::InsertHead(const void* pBuffer, Uint32 nLen, Uint32 SplitSize/* = 0*/)
{
    m_TotalLen += nLen;
    if (0 == SplitSize) {
        m_ListBuffer.push_front(CMkBuffer(pBuffer, nLen));
    } else {
        Uint32 CurLen = 0;
        Uint32 nOffset = 0;
        while (nLen > SplitSize) {
            m_ListBuffer.push_front(CMkBuffer((Uint8*)pBuffer + nLen - SplitSize, SplitSize));
            nLen -= SplitSize;
        }
        m_ListBuffer.push_front(CMkBuffer(pBuffer, nLen));
    }
    return NoneError;
}

Uint32 CMkBufferList::Append(const CMkBufferList& BufList)
{
    MkListBuffer::const_iterator it = BufList.GetBufferList().begin();
    for (; it != BufList.GetBufferList().end(); it++) {
        Append(*it);
    }
    return NoneError;
}

Uint32 CMkBufferList::Append(const CMkBuffer& Buffer)
{
    m_ListBuffer.push_back(Buffer);
    m_TotalLen += Buffer.GetLength();
    return NoneError;
}

Uint32 CMkBufferList::Append(const void* pBuffer, Uint32 nLen, Uint32 SplitSize/* = 0*/)
{
    m_TotalLen += nLen;
    if (0 == SplitSize) {
        m_ListBuffer.push_back(CMkBuffer(pBuffer, nLen));
    } else {
        Uint32 nOffset = 0;
        Uint32 CurLen = 0;
        while (nLen > 0) {
            CurLen = nLen > SplitSize ? SplitSize : nLen;
            m_ListBuffer.push_back(CMkBuffer((Int8*)pBuffer + nOffset, CurLen));
            nLen -= CurLen;
            nOffset += CurLen;
        }
    }
    return NoneError;
}

Uint32 CMkBufferList::RemoveBegin(Uint32 RemoveCount)
{
    if (RemoveCount > m_TotalLen) {
        RemoveCount = m_TotalLen;
    }
    m_TotalLen -= RemoveCount;
    MkListBuffer::iterator it = m_ListBuffer.begin();
    while (it != m_ListBuffer.end()) {
        if (RemoveCount >= it->GetLength()) {
            RemoveCount -= it->GetLength();
            it = m_ListBuffer.erase(it);
        } else if (0 == RemoveCount) {
            break;
        } else {
            CMkBuffer TmpBuffer = CMkBuffer((Uint8*)it->GetBuffer() + RemoveCount, it->GetLength() - RemoveCount);
            m_ListBuffer.erase(it);
            RemoveCount = 0;
            m_ListBuffer.push_front(TmpBuffer);
            break;
        }
    }
    return NoneError;
}

Uint32 CMkBufferList::GetBuffer(const Uint32& Offset, const Uint32& BufferLen, CMkBufferList& BufferList) const
{
    if (Offset + BufferLen > m_TotalLen) {
        return InvalidParams;
    }
    Uint32 TmpOffset = Offset;
    Uint32 TmpBufferLen = BufferLen;
    MkListBuffer::const_iterator it = m_ListBuffer.begin();
    for (; it != m_ListBuffer.end(); it++) {
        if (TmpOffset >= it->GetLength()) {
            TmpOffset -= it->GetLength();
            continue;
        } else {
            CMkBuffer CopyBuffer(*it);
            if (0 != TmpOffset) {
                CopyBuffer = CMkBuffer((const Uint8*)it->GetBuffer() + TmpOffset, it->GetLength() - TmpOffset);
                TmpOffset = 0;
            }
            if (CopyBuffer.GetLength() < TmpBufferLen) {
                BufferList.Append(CopyBuffer);
                TmpBufferLen -= CopyBuffer.GetLength();
            } else {
                BufferList.Append(CopyBuffer.GetBuffer(), TmpBufferLen);
                TmpBufferLen = 0;
                break;
            }
        }
    }
    return NoneError;
}

CMkStorageBufferList::CMkStorageBufferList()
    : m_TotalLen(0)
{

}
//
//Uint32 CMkStorageBufferList::InsertHead(const CMkBufferList& BufList)
//{
//    MkList<CMkBuffer*>::const_reverse_iterator it = BufList.GetBufferList().rbegin();
//    for (; it != BufList.GetBufferList().rend(); it++) {
//        InsertHead(*it,);
//    }
//    return NoneError;
//}
//
//Uint32 CMkStorageBufferList::InsertHead(const CMkBuffer& Buffer, BOOL bNew/* = FALSE*/)
//{
//    m_ListBuffer.push_front(new CMkBuffer(Buffer, bNew));
//    m_TotalLen += Buffer.GetLength();
//    return NoneError;
//}
//
//Uint32 CMkStorageBufferList::InsertHead(const void* pBuffer, Uint32 nLen, Uint32 SplitSize/* = 0*/, BOOL bNew/* = FALSE*/)
//{
//    m_TotalLen += nLen;
//    if (0 == SplitSize) {
//        m_ListBuffer.push_front(new CMkBuffer(pBuffer, nLen, bNew));
//    } else {
//        Uint32 CurLen = 0;
//        Uint32 nOffset = 0;
//        while (nLen > SplitSize) {
//            m_ListBuffer.push_front(new CMkBuffer((Uint8*)pBuffer + nLen - SplitSize, SplitSize, bNew));
//            nLen -= SplitSize;
//        }
//        m_ListBuffer.push_front(new CMkBuffer(pBuffer, nLen, bNew));
//    }
//    return NoneError;
//}
//
Uint32 CMkStorageBufferList::Append(const CMkBufferList& BufList)
{
    MkListBuffer::const_iterator it = BufList.GetBufferList().begin();
    for (; it != BufList.GetBufferList().end(); it++) {
        Append(*it);
    }
    return NoneError;
}

Uint32 CMkStorageBufferList::Append(const CMkBuffer& Buffer)
{
    m_ListBuffer.push_back(new CMkStorageBuffer(Buffer));
    m_TotalLen += Buffer.GetLength();
    return NoneError;
}

Uint32 CMkStorageBufferList::Append(const void* pBuffer, Uint32 nLen, Uint32 SplitSize/* = 0*/)
{
    m_TotalLen += nLen;
    if (0 == SplitSize) {
        m_ListBuffer.push_back(new CMkStorageBuffer(pBuffer, nLen));
    } else {
        Uint32 nOffset = 0;
        Uint32 CurLen = 0;
        while (nLen > 0) {
            CurLen = nLen > SplitSize ? SplitSize : nLen;
            m_ListBuffer.push_back(new CMkStorageBuffer((Int8*)pBuffer + nOffset, CurLen));
            nLen -= CurLen;
            nOffset += CurLen;
        }
    }
    return NoneError;
}

Uint32 CMkStorageBufferList::RemoveBegin(Uint32 RemoveCount)
{
    if (RemoveCount > m_TotalLen) {
        RemoveCount = m_TotalLen;
    }
    m_TotalLen -= RemoveCount;
    MkListStorageBuffer::iterator it = m_ListBuffer.begin();
    while (it != m_ListBuffer.end()) {
        if (RemoveCount >= (*it)->GetLength()) {
            RemoveCount -= (*it)->GetLength();
            delete *it;
            it = m_ListBuffer.erase(it);
        } else if (0 == RemoveCount) {
            break;
        } else {
            CMkStorageBuffer *pBuff = new CMkStorageBuffer((Uint8*)(*it)->GetBuffer() + RemoveCount, (*it)->GetLength() - RemoveCount);
            delete *it;
            m_ListBuffer.erase(it);
            RemoveCount = 0;
            m_ListBuffer.push_front(pBuff);
            break;
        }
    }
    return NoneError;
}

Uint32 CMkStorageBufferList::GetBeginBuildTime(CMkTime& BeginTime) const
{
    if (m_ListBuffer.empty()) {
        BeginTime = NowMkTime;
        return NoneError;
    }
    BeginTime = (*m_ListBuffer.begin())->GetBuildTime();
    return NoneError;
}

void CMkStorageBufferList::Clear()
{
    MkListStorageBuffer::iterator it = m_ListBuffer.begin();
    for (; it != m_ListBuffer.end(); it++) {
        MkDelete(*it);
    }
    m_ListBuffer.clear();
    m_TotalLen = 0;
}

Uint32 CMkStorageBufferList::GetBufferList(CMkBufferList& BufferList) const
{
    MkListStorageBuffer::const_iterator it = m_ListBuffer.begin();
    for (; it != m_ListBuffer.end(); it++) {
        BufferList.Append((*it)->GetBuffer(), (*it)->GetLength());
    }
    return NoneError;
}


CMkBuffer::~CMkBuffer()
{
    m_pBuf = nullptr;
    m_nLen = 0;
}

CMkStorageBuffer::~CMkStorageBuffer()
{
    MkFree(m_pBuf);
    m_nLen = 0;
}

CMkBufferList::~CMkBufferList()
{
    m_ListBuffer.clear();
    m_TotalLen = 0;
}

CMkStorageBufferList::~CMkStorageBufferList()
{
    //Clear();
}